package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollUtil;
import com.itheima.domain.mongo.*;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@Service //dubbo
public class MovementServiceImpl implements MovementService {

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    IdService idService;

    @Override
    public void save(Movement movement) {
        //0.获取大数据需要的动态 pid,设置给动态
        Long pid = idService.getNextId(ConstantUtil.MOVEMENT_ID);
        movement.setPid(pid);

        //1.将动态保存到详情表
        mongoTemplate.save(movement);

        //1.1 获取动态详情的id
        ObjectId movementId = movement.getId();

        //1.2 获取用户id
        Long userId = movement.getUserId();

        //2.将动态保存到我的动态表中
        MyMovement myMovement = new MyMovement();

        //2.1封装我的动态对象
        myMovement.setPublishId(movementId);//动态id
        myMovement.setCreated(System.currentTimeMillis());

        //2.2保存到我的动态表中
        mongoTemplate.save(myMovement,ConstantUtil.MOVEMENT_MINE+userId);

        //3.查询我的好友列表
        Query query = new Query(
                Criteria.where("userId").is(userId)
        );
        List<Friend> friends = mongoTemplate.find(query, Friend.class);

        //4.遍历好友列表,将动态保存到好友的好友动态表中
        if (CollUtil.isNotEmpty(friends)) {
            for (Friend friend : friends) {
                //4.1 获取好友id
                Long friendId = friend.getFriendId();

                //4.2 创建好友动态对象,且封装
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setPublishId(movementId);//动态id
                friendMovement.setUserId(userId);//发布人(当前登陆用户)id
                friendMovement.setCreated(System.currentTimeMillis());

                //4.3 保存到好友的好友动态表中
                mongoTemplate.save(friendMovement,ConstantUtil.MOVEMENT_FRIEND+friendId);
            }
        }
    }

    @Override
    //我的动态
    public PageBeanVo findMyMovementByPage(int pageNum, int pageSize, Long userId) {
        //1.创建条件查询对象(分页和排序)
        Query query = new Query()
                .skip((pageNum-1)*pageSize).limit(pageSize)//分页
                .with(Sort.by(Sort.Order.desc("created"))//排序
                );

        //2.查询我的动态表(只有动态id)
        List<MyMovement> myMovements = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        //3.遍历我的动态集合,获取每个动态id,查询动态详情表,获取每个动态的详情,放入list中
        //3.0 定义一个审核不通过的计数器
        int failStateCount = 0;

        // 3.1 定义一个movement集合
        ArrayList<Movement> movementList = new ArrayList<>();
        if (CollUtil.isNotEmpty(myMovements)) {
            for (MyMovement myMovement : myMovements) {
                //3.2 获取动态id
                ObjectId movementId = myMovement.getPublishId();

                //3.3 通过动态id 查询动态详情表获取动态详情对象
                Movement movement = mongoTemplate.findById(movementId, Movement.class);

                //3.4 将审核通过详情对象放入list中
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }else {
                    failStateCount ++;
                }
            }
        }

        //4.查询总记录数
        long count = mongoTemplate.count(query, ConstantUtil.MOVEMENT_MINE + userId);

        //5.返回PageBeanVo
        return new PageBeanVo(pageNum,pageSize,count-failStateCount,movementList);
    }

    @Override
    public PageBeanVo findFriendMovementByPage(int pageNum, int pageSize, Long userId) {
        //1.创建条件查询对象(分页和排序)
        Query query = new Query()
                .skip((pageNum-1)*pageSize).limit(pageSize)
                .with(Sort.by(Sort.Order.desc("created")));

        //2.查询我的好友动态表(只有动态id和好友id)
        List<FriendMovement> friendMovements = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //3.遍历好友动态集合,获取每个动态id,查询动态详情表,获取每个动态的详情,放入list中
        //3.0 设置一个审核失败的计数器
        int failStateCount = 0;

        //3.1 创建一个movementList
        List<Movement> movementList = new ArrayList<>();

        //3.2 遍历好友动态集合
        if (CollUtil.isNotEmpty(friendMovements)) {
            for (FriendMovement friendMovement : friendMovements) {
                //3.3 获取movementid
                ObjectId movementId = friendMovement.getPublishId();

                //3.4 查询动态详情movement
                Movement movement = mongoTemplate.findById(movementId, Movement.class);

                //3.5 将审核通过movement放入list中
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }else {
                    failStateCount ++;
                }
            }
        }

        //4.查询总记录数
        long count = mongoTemplate.count(query, ConstantUtil.MOVEMENT_FRIEND + userId);

        //5.返回PageBeanVo
        return new PageBeanVo(pageNum,pageSize,count-failStateCount,movementList);
    }

    @Override
    public PageBeanVo findRecommendMovementByPage(int pageNum, int pageSize, Long userId) {
        //1.创建条件对象(userId,分页,排序)
        Query query = new Query(
                Criteria.where("userId").is(userId)
        ).skip((pageNum-1)*pageSize).limit(pageSize) //分页
        .with(Sort.by(Sort.Order.desc("created")));//排序

        //2.查询推荐动态表(只有动态id,得分等)
        List<RecommendMovement> recommendMovements = mongoTemplate.find(query, RecommendMovement.class);

        //3.遍历推荐动态表,获取每个动态id
        //3.1 定义审核失败计数器
        int failStatCount = 0;

        //3.2 定义movementList
        List<Movement> movementList = new ArrayList<>();

        if (CollUtil.isNotEmpty(recommendMovements)) {
            for (RecommendMovement recommendMovement : recommendMovements) {
                //3.3 获取movementId,查询动态详情
                ObjectId movementId = recommendMovement.getPublishId();//动态id
                Movement movement = mongoTemplate.findById(movementId, Movement.class);

                //4.查询动态详情信息,将审核通过的动态放入一个list中
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }else {
                    failStatCount ++;
                }
            }
        }

        //5.查询总记录数
        long count = mongoTemplate.count(query, RecommendMovement.class);

        //6.返回pageBeanVo
        return new PageBeanVo(pageNum,pageSize,count - failStatCount,movementList);
    }

    @Override
    public Movement findById(String id) {
        return mongoTemplate.findById(new ObjectId(id),Movement.class);
    }

    @Override
    public PageBeanVo findMovementByCondition4Page(Long uid, Integer state, int pageNum, int pageSize) {
        //1.创建条件查询对象
        Query query = new Query().skip((pageNum-1)*pageSize).limit(pageSize);

        //1.1 判断是否查询个人动态信息
        if (uid != null) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }

        //1.2 判断state有无值
        if (state != null) {
            query.addCriteria(Criteria.where("state").is(state));
        }

        //2.查询动态表
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        //3.查询总记录数
        long count = mongoTemplate.count(query, Movement.class);

        //4.封装PageBeanVo返回
        return new PageBeanVo(pageNum,pageSize,count,movementList);
    }

    @Override
    public void update(Movement movement) {
        mongoTemplate.save(movement);
    }
}
